<?php defined('SYSPATH') or die('No direct script access.');

/**
 * Front Class
 * 
 * This class handles the front controller to make code more reuseable and makes it easier
 * to integrate AuthorEyes into your own templating system.
 * 
 * => Libraries => Kohana: Session, Validation - AuthorEyes: AE_Validation, Authoreyes
 * => Helpers   => Kohana: url, form - AuthorEyes: authoreyes
 *
 * -----------------------------------------------------------------------------
 * Copyright (C) 2008   Patrick Clark (pubblichi.com/blog)
 * -----------------------------------------------------------------------------
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ------------------------------------------------------------------------------
 * @package     AuthorEyes
 * @subpackage  Libraries
 * @category    Authentication
 * @author      Patrick Clark (Tap)
 * @copyright   Copyright (c) 2008, pubblichi.com
 * @license     http://www.gnu.org/licenses/lgpl.html
 * @link        http://www.pubblichi.com/authoreyes
 * @info        This is a complete rewrite of the FreakAuth Light authentication library,
 * @info        written specifically for Kohana.
 * @info     	FreakAuth Light written by Daniel Vecchiato (danfreak) & Christophe Gragnic (grahack)
 * @info        Visit www.4webby.com/freakauth to download FreakAuth Light for CodeIgniter
 * @version     0.1
 *
 */
class Front_Core {
	/*-------------+
	|  PROPERTIES  |
	+-------------*/
	// Model instances.
	protected $user_mdl;
	protected $country_mdl;
	
	// AuthorEyes library instances.
	protected $authoreyes;
	protected $ae_validation;
	
	/*----------+
	|  METHODS  |
	+----------*/
	/**
	 * Initialize the Front class (library).
	 * 
	 * @return void
	 */
	public function __construct()
	{
		// Create new instances of our models.
		$this->user_mdl = new User_Model;
		if (Config::item('authoreyes.ae_use_country'))
		{
			$this->country_mdl = new Country_Model;
		}
		
		// Create new instances of our AE_Validation and Authoreyes libraries.
		$this->ae_validation = new AE_Validation;
		$this->authoreyes = new Authoreyes;
		
		//$this->ae_validation->set_error_delimiters(Config::item('authoreyes.ae_error_delimiter_open'), Config::item('authoreyes.ae_error_delimiter_close'));
	}
	
	/**
	 * Displays the login form.
	 * 
	 * Usage:
	 *  Load the library in your controller.
	 *    - $this->front = new Front;
	 *    
	 *    $data['ae'] = $this->front->login(); // <-- Assign it to a variable.
	 *    $this->your_view = new View('your_view', $data); // <-- Pass it to your view.
	 * 
	 * This will also work in your controllers:
	 *    - echo $this->front->login();
	 *    
	 * Alternativately, you can use the helper function display_login_form().
	 * 
	 * @return object
	 */
	public function login()
	{
		// Checks if a valid user is already logged in.
		if ($this->authoreyes->belongs_to_group('user'))
		{
			// We can arrive here after two different things.
			// !!!! CHECK TO SEE IF THIS IS THE CORRECT WAY TO WORK A SESSION (use singleton instance?) !!!!
			$requested_page = $this->authoreyes->session->get('requested_page');
			
			// Ensure that the requested page returns something.
			if ($requested_page == '')
			{
				// If the user clicks on the login link, display username 
				// and an 'already logged in' flash message.
				$msg = $this->authoreyes->get_username().', '.Kohana::lang('authoreyes.ae_website.already_logged_in_message');
			}
			else
			{
				// A lack of credentials after being redirected by the 'redirect to requested page'
				// process (after a successful login that followed a denied access).
				$msg = Kohana::lang('authoreyes.ae_website.no_credentials_user_message');
			}
			
			// Set FLASH MESSAGE.
			authoreyes_help::flash_message($msg);
			
			// Redirects to homepage
			url::redirect('', 301);
		}
		else
		{
			// Sets the neccessary form field labels.
			$fields['username'] = Kohana::lang('authoreyes.ae_website.username_label');
			$fields['password'] = Kohana::lang('authoreyes.ae_website.user_password_label');
			
			// Sets the field validation rules.
			$rules['username'] = Config::item('authoreyes.ae_username_field_validation_login');
			$rules['password'] = Config::item('authoreyes.ae_user_password_field_validation_login');
			
			// Checks whether captchas will be used for login.
			if (Config::item('authoreyes.ae_captcha_settings.use_captcha_login'))
			{
				// Sets the field label and validation rules for the captcha.
				$fields['security'] = Kohana::lang('authoreyes.ae_captcha.captcha_label');
				$rules['security'] = Config::item('authoreyes.ae_user_captcha_field_validation');
			}
			
			// ----------------------------------------------- //
			// ADD MORE FIELDS AND RULES HERE IF YOU NEED THEM //
			// ----------------------------------------------- //
			
			// Sets the validation rules and fields.
			$this->ae_validation->set_fields($fields);
			$this->ae_validation->set_rules($rules);
			
			// Let's run the individual validation of username and password.
			$validation_response = $this->ae_validation->run();
			
			// If you change the keys of the validation rules, remember to adjust the following 2 lines.
			// i.e. change $this->ae_validation->username to $this->ae_validation->your_username_key.
			$username_login = $this->ae_validation->username;
			$password_login = $this->ae_validation->password;
			
			// If everything went OK, let's log the user in and redirect him to the homepage.
			if ($validation_response == TRUE 
			    AND $this->ae_validation->login_check($username_login, $password_login)
				AND $this->authoreyes->login())
			{
				// Here is the 'redirect to requested page after login block.
				// We test if the visitor was denied and sent to the login form.
				$requested_page = $this->authoreyes->session->get('requested_page');
				
				if ($requested_page != '')
				{
					// We have to keep the page info once again in case the user is still denied on the request
					// page (Otherwise the 'already logged in' message is displayed).
					$this->authoreyes->session->set_flash('requested_page', $requested_page);
					url::redirect($requested_page, 301);
				}
				
				// If no page was requested before, let's redirect the user according to his/her role.
				$role = $this->authoreyes->session->get($role);
				
				switch ($role)
				{
					case ('superadmin'):
					case ('admin'):
					{
						// On success, redirect (super)admin to default page.
						url::redirect(Config::item('authoreyes.ae_admin_login_success_action'));
						break;
					}
					default:
					{
						// On success, redirect user to default page.
						url::redirect(Config::item('authoreyes.ae_login_success_action'));
					}
				}
			}
			// Else, display the login form (for the first time, or once again).
			else
			{
				// Keep the page that was requested for the next login attempt.
				$this->authoreyes->session->keep_flash('requested_page');
				
				if (Config::item('authoreyes.ae_captcha_settings.use_captcha_login'))
				{
					$action = '_login';
					// FIGURE OUT HOW TO INTEGRATE BUILT IN CAPTCHA LIBRARY W/ FRONT LIBRARY.
				}
			}
		}
	}
	
	/**
	 * Handles the logout action.
	 * 
	 * @return void
	 */
	public function logout()
	{
		$this->authoreyes->logout();
	}
	
	/**
	 * Displays the registration form.
	 * 
	 * Usage:
	 *  Load the library in your controller.
	 *    - $this->front = new Front;
	 *    
	 *    $data['ae'] = $this->front->register(); // <-- Assign it to a variable.
	 *    $this->your_view = new View('your_view', $data); // <-- Pass it to your view.
	 * 
	 * This will also work in your controllers:
	 *    - echo $this->front->register();
	 *    
	 * Alternativately, you can use the helper function display_registration_form().
	 * 
	 * @return object
	 */
	public function register()
	{
		// If users are not allowed to register.
		if (!Config::item('authoreyes.ae_allow_user_registration'))
		{
			// Redirect to the homepage.
			url::redirect('', 301);
		}
		else
		{
			// Sets the necessary form fields.
			$fields['username'] = Kohana::lang('authoreyes.ae_website.username_label');
			$fields['password'] = Kohana::lang('authoreyes.ae_website.user_password_label');
			$fields['password_confirm'] = Kohana::lang('authoreyes.ae_website.user_password_confirm_label');
			$fields['email'] = Kohana::lang('authoreyes.ae_website.user_email_label');
			
			// Sets the validation rules.
			$rules['username'] = Config::item('authoreyes.ae_username_field_validation_login');
			$rules['password'] = Config::item('authoreyes.ae_user_password_field_validation_login');
			$rules['password_confirm'] = Config::item('authoreyes.ae_password_required_confirm_validation')."|matches[".'password'."]";
			$rules['email'] = Config::item('authoreyes.ae_user_email_field_validation_register');
		}
		
		// Do we also want to know the users country?
		if (Config::item('authoreyes.ae_use_country'))
		{
			$fields['country_id'] = Kohana::lang('authoreyes.ae_website.user_country_label');
			$rules['country_id'] = Config::item('authoreyes.ae_user_country_field_validation_register');
		}
		
		// Do we also want to secure the registration with a Captcha?
		if (Config::item('authoreyes.ae_captcha_settings.use_captcha_register'))
		{
			$fields['security'] = Kohana::lang('authoreyes.ae_captcha.captcha_label');
			$rules['security'] = Config::item('authoreyes.ae_user_captcha_field_validation');
		}
		
		// ----------------------------------------------- //
		// ADD MORE FIELDS AND RULES HERE IF YOU NEED THEM //
		// ----------------------------------------------- //
		
		$this->ae_validation->set_fields($fields);
		$this->ae_validation->set_rules($rules);
		
		// If everything went okay.
		if ($this->ae_validation->run() AND $this->authoreyes->register())
		{
			$data['heading'] = Kohana::lang('authoreyes.ae_website.register_label');
			
			// Normal registration with e-mail validation.
			if (!Config::item('authoreyes.ae_register_direct'))
			{
				// Return the view to display the successful registration information.  RENDER???
				return new View(Config::item('authoreyes.ae_register_success_view'), $data);
			}
			// Direct registration.
			else
			{
				url::redirect(Config::item('authoreyes.ae_controller_conventions.login_uri'). 301);
			}
		}
		// Redisplay the registration form.
		else
		{
			// If we want to know the users country, let's populate the select menu.
			if (Config::item('authoreyes.ae_use_country'))
			{
				$data['countries'] = $this->authoreyes->user_mdl->get_countries_for_select();
			}
			
			// If we want to secure the registration form using a captcha, let's generate it.
			if (Config::item('authoreyes.ae_captcha_settings.use_captcha_register'))
			{
				// FIGURE OUT HOW TO INTERGRATE CAPTCHA LIBRARY //
			}
			
			// Display the view.
			$data['heading'] = Kohana::lang('authoreyes.ae_website.register_label');
			// Return the view to display the registration form.  RENDER???
			return new View(Config::item('authoreyes.ae_register_view'), $data);
		}
	}
	
	/**
	 * Displays the user activation.
	 * 
	 * Usage:
	 *  Load the library in your controller.
	 *    - $this->front = new Front;
	 *    
	 *    $data['ae'] = $this->front->activation(); // <-- Assign it to a variable.
	 *    $this->your_view = new View('your_view', $data); // <-- Pass it to your view.
	 * 
	 * This will also work in your controllers:
	 *    - echo $this->front->activation();
	 * 
	 * @return object
	 */
	public function activation()
	{
		// Passes the URI segments to Authoreyes.php (usertemp id segment [3], activation code segment [4]).
		// If the activation is successful, displays the success page.
		if ($this->authoreyes->activation($this->uri->segment(3), $this->uri->segment(4)))
		{
			$data['heading'] = Kohana::lang('authoreyes.ae_website.activation_label');
			return new View(Config::item('authoreyes.ae_register_activation_success_view'), $data);
		}
		// If activation is unsuccessful, display a failure message.
		else
		{
			$data['heading'] = Kohana::lang('authoreyes.ae_website.activation_label');
			return new View(Config::item('authoreyes.ae_register_activation_failed_view'), $data);
		}
	}
	
	/**
	 * Handles the forgotten password form.
	 * 
	 * Usage:
	 *  Load the library in your controller.
	 *    - $this->front = new Front;
	 *    
	 *    $data['ae'] = $this->front->forgotten_password(); // <-- Assign it to a variable.
	 *    $this->your_view = new View('your_view', $data); // <-- Pass it to your view.
	 * 
	 * This will also work in your controllers:
	 *    - echo $this->front->forgotten_password();
	 * 
	 * @return object
	 */
	public function forgotten_password()
	{
		// Sets the neccessary form fields and rules.
		$fields['email'] = Kohana::lang('authoreyes.ae_website.user_email_label');
		$rules['email'] = Config::item('authoreyes.ae_user_email_field_validation_forgotten');
		
		// Do we also want to use a captcha?
		if (Config::item('authoreyes.ae_captcha_settings.use_captcha_forgot_password'))
		{
			$fields['security'] = Kohana::lang('authoreyes.ae_captcha.captcha_label');
			$rules['security'] = Config::item('authoreyes.ae_user_captcha_field_validation');
		}
		
		// ----------------------------------------------- //
		// ADD MORE FIELDS AND RULES HERE IF YOU NEED THEM //
		// ----------------------------------------------- //
		
		$this->ae_validation->set_fields($fields);
		$this->ae_validation->set_rules($rules);
		
		// If it got POST data and they validate, display the success page.
		if ($this->ae_validation->run() AND $this->authoreyes->forgotten_password())
		{
			return new View(Config::item('authoreyes.ae_forgotten_password_success_view'));
		}
		// Display the initial forgotten password form.
		else
		{
			if (Config::item('authoreyes.ae_captcha_settings.use_captcha_forgot_password'))
			{
				// FIGURE OUT HOW TO INTERGRATE CAPTCHA LIBRARY //
			}
			
			// Display the form.
			$data['heading'] = Kohana::lang('authoreyes.ae_website.forgotten_password_label');
			return new View(Config::item('authoreyes.ae_forgotten_password_view'));
		}
	}
	
	/**
	 * Handles the password reset form.
	 * 
	 * Usage:
	 *  Load the library in your controller.
	 *    - $this->front = new Front;
	 *    
	 *    $data['ae'] = $this->front->forgotten_password_reset(); // <-- Assign it to a variable.
	 *    $this->your_view = new View('your_view', $data); // <-- Pass it to your view.
	 * 
	 * This will also work in your controllers:
	 *    - echo $this->front->forgotten_password_reset();
	 * 
	 * @return object
	 */
	public function forgotten_password_reset()
	{
		// Checks if the password has been reset, and displays the success page. (Generate random PW, store in DB, send to user)
		if ($this->authoreyes->forgotten_password_reset($this->uri->segment(3), $this->uri->segment(4)))
		{
			return new View(Config::item('authoreyes.ae_forgotten_password_reset_success_view'));
		}
		// Display failure page.
		else
		{
			return new View(Config::item('authoreyes.ae_forgotten_password_reset_failed_view'));
		}
	}
	
	/**
	 * Handles the change password procedure.
	 * 
	 * Let's the user reset their password if they have forgotten it.
	 * 
	 * Usage:
	 *  Load the library in your controller.
	 *    - $this->front = new Front;
	 *    
	 *    $data['ae'] = $this->front->activation(); // <-- Assign it to a variable.
	 *    $this->your_view = new View('your_view', $data); // <-- Pass it to your view.
	 * 
	 * This will also work in your controllers:
	 *    - echo $this->front->activation();
	 * 
	 * @return object
	 */
	public function change_password()
	{
		// Sets the necessary form fields.
		$fields['username'] = Kohana::lang('authoreyes.ae_website.username_label');
		$fields['old_password'] = Kohana::lang('authoreyes.ae_website.old_password_label');
		$fields['password'] = Kohana::lang('authoreyes.ae_website.new_password_label');
		$fields['password_confirm'] = Kohana::lang('authoreyes.ae_website.retype_new_password_label');
		
		// Sets the validation rules.
		$rules['username'] = Config::item('authoreyes.ae_username_field_validation_login');
		$rules['old_password'] = Config::item('authoreyes.ae_user_password_field_validation_login');
		$rules['password'] = Config::item('authoreyes.ae_password_required_validation');
		$rules['password_confirm'] = Config::item('authoreyes.ae_password_required_confirm_validation')."|matches[".'password'."]";
		
		// ----------------------------------------------- //
		// ADD MORE FIELDS AND RULES HERE IF YOU NEED THEM //
		// ----------------------------------------------- //
		
		$this->ae_validation->set_fields($fields);
		$this->ae_validation->set_rules($rules);
		
		// If it got POST data and they validate, display the success page.
		if ($this->ae_validation->run() AND $this->authoreyes->change_password())
		{
			// Sets FLASH MESSAGE.
			$msg = Kohana::lang('authoreyes.ae_change_password.change_password_success_message');
			authoreyes_help::flash_message($msg);
			
			// Redirect to homepage.
			url::redirect('', 301);
		}
		// Redisplay change password page.
		else
		{
			$data['heading'] = Kohana::lang('authoreyes.ae_website.change_password_label');
			return new View(Config::item('authoreyes.ae_change_password_view'), $data);
		}
	}
} // End Front_Core
?>